package com.example.circleequation;

import android.graphics.*;

public class CircleEquation {
	PointF _center;
	int _radius;
	
	public CircleEquation(PointF center, int radius)
	{
		_center = center;
		_radius = radius;
	}
	
	public CircleEquation(float x, float y, int radius)
	{
		_center = new PointF(x, y);
		_radius = radius;
	}
	
	private float[] CalculateX(float initialX, int count)
	{
		float fractionDegree = (float)((2 * Math.PI) / count);
		float initialDegree = - (float)Math.PI;
		float[] result = new float[count];
		result[0] = initialX;
		
		float tempDegree = 0.0f;
		for(int i = 1; i < count; i++)
		{
			tempDegree = initialDegree - fractionDegree * i;
			result[i] = _center.x + _radius * (float)Math.cos(tempDegree);
		}
		
		return result;
	}
	
	private float[] CalculateEquation(float x)
	{
		// Circle Equation
		// x^2 + y^2 = r^2
		//(x-cx)^2 + (y-cy)^2 = r^2 : cx, cy = center
		
		// A + B = C
		double cSide = Math.pow(_radius, 2.0);
		double aSide = Math.pow((x - _center.x), 2.0);
		
		double bSide = Math.sqrt(cSide-aSide);
		
		float[] result = new float[2]; 
		
		result[0] = (float)(-bSide + _center.y);
		result[1] = (float)(bSide + _center.y);
		
		return result;
	}
	
	public void SetCenter(PointF center)
	{
		_center = center;
	}
	
	public void SetCenter(float x, float y)
	{
		_center = new PointF(x, y);
	}
	
	public void SetRadius(int radius)
	{
		_radius = radius;
	}
	
	/**
	 * Get points at Circle Equation.
	 * @param pointCount : Integer( 2*(x + 1) )
	 * @return Points at Circle Equation.
	 * If pointCount was Odd number, return null.
	 * Points start most left point and Clock wise;
	 */
	public PointF[] GetPoints(int pointCount)
	{
		if(pointCount % 2 != 0)
			return null;
		
		// Initialize Result Point
		PointF[] resultPoint = new PointF[pointCount];
		for(int i = 0; i < pointCount; i++)
			resultPoint[i] = new PointF();
		
		// Calculate Fraction
		int fraction = (int)Math.ceil((_radius * 2) / ((pointCount-2)/2 + 1));
		// Initialize X value of Result Point
		resultPoint[0].x = _center.x - _radius;
		
		// Calculate X value of Points
		float[] x = CalculateX(resultPoint[0].x, pointCount);
		for(int i = 1; i < pointCount; i++)
		{
			resultPoint[i].x = x[i];
		}
		
		// Circle Equation
		// x^2 + y^2 = r^2
		//(x-cx)^2 + (y-cy)^2 = r^2 : cx, cy = center
		for(int i = 0; i < pointCount; i++)
		{
			if(i <= pointCount/2)
				resultPoint[i].y = CalculateEquation(resultPoint[i].x)[0];
			else
				resultPoint[i].y = CalculateEquation(resultPoint[i].x)[1];
		}
		
		return resultPoint;
	}
	
	public Rect[] GetRects(int rectCount, int rectWidth)
	{
		PointF[] centers = GetPoints(rectCount);
		Rect[] rects = new Rect[rectCount];
		
		// initialize rects
		for(int i = 0; i < rectCount; i++){
			rects[i] = new Rect();
		}
		
		// calculate rects
		int left = 0;
		int top = 0;
		for(int i = 0; i < rectCount; i++){
			left = (int)(centers[i].x - rectWidth/2);
			top = (int)(centers[i].y - rectWidth/2);
			rects[i].set(left, top, left+rectWidth, top+rectWidth);
		}
		
		return rects;
	}
}